package samples.d2.lines 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.utils.clearInterval;
	import flash.utils.setInterval;
	import graphics.raster.Bresenham;
	import samples.BaseSample;
	import shapes.shapes2D.Dot;
	import utils.GeomUtils;
	
	/**
	 * @author Nicolas Barradeau
	 * http://en.nicoptere.net
	 */
	public class Subtrate extends BaseSample
	{
		
		private var backgroundColor:uint = 0;
		private var bd:BitmapData;

		private var p:Dot;
		private var colors:Array;
		private var pts:Vector.<Dot>;
		private var tracks:Vector.<Dot>;
		
		private var iterations:int;
	
		private var _displace:Function = function ( p:Dot ):void
		{
			
			p.x += Math.cos( p.z );
			p.y += Math.sin( p.z );
			
			//p.x += Math.cos( p.z + ( Math.PI / 360 * iterations ) );// ) GeomUtils.normalize( ( , -2, 1 )// int(    );
			//p.y += Math.sin( p.z  );
			
			//p.x += Math.cos( p.z + ( Math.PI / 180 * iterations ) );// ) GeomUtils.normalize( ( , -2, 1 )// int(    );
			//p.y += Math.sin( p.z - ( Math.PI / 180 * iterations ));
			//p.y -= Math.cos( p.x ) * 100;
				
		}

		public function Subtrate() 
		{
			colors = [ 
						//0xFFFFFFFF, 0xFFEEEEEE, 0xFFDDDDDD, 0xFFCCCCCC,
						//0xFFBBBBBB, 0xFFAAAAAA, 0xFF999999, 0xFF888888, 
						//0xFF777777, 0xFF666666, 0xFF555555, 0xFF444444,	
						//0xFF333333, 0xFF222222, 0xFF111111, 0xFF000000  
						];
			
			var i:int = 256;
			while ( i-- )
			{
				colors.push( 0xFF << 24 | i << 16 | i << 8 | i );
			}
			colors = [ 0xFFFFFFFF ];
			
			bd = new BitmapData( sw, sh, true, 0 );
			var bmp:Bitmap = new Bitmap( bd ) ;// , 'auto', true )
			addChild( bmp );
			
			Bresenham.bitmapData = bd;
			
		}

		public function reset( total:int, distance:int = 10, sources:Vector.<Dot> = null ):void
		{
			bd.fillRect( bd.rect, 0 );
			
			pts = new Vector.<Dot>();
			tracks = new Vector.<Dot>();
			iterations = 0;
			var i:int = total;
			if ( sources != null )
			{
			
				for each( p in sources )
				{
					i = total;
					while( i-- )
					{
						//p.z = ( ( 1 + int( Math.random() * 4 ) ) * ( Math.PI / 2 ) );
						
						var angle:Number = ( Math.PI * 2 / total ) * i;
						var np:Dot = new Dot( 
												//p.x + Math.cos( angle ) * distance, 
												//p.y + Math.sin( angle ) * distance, 
												p.x + ( Math.random() - .5 ) * distance, 
												p.y + ( Math.random() - .5 ) * distance,  
												iterations
											);
						
						//var angle:Number = ( Math.PI * 2 / total ) * i;
						np.z = angle;// Math.random() * Math.PI * 2;
						pts.push( np );
						iterations++;
						
					}
				}
				
			}
			else 
			{
				i = total;
				while( i-- )
				{
					
					p = new Dot( Math.random() * sw, Math.random() * sh,  i );
					p.z = Math.random() * Math.PI * 2;// ( ( 1 + int( Math.random() * 4 ) ) * ( Math.PI / 2 ) );
					pts.push( p );
					
				}
			}
			
			iterations = 0;
			
			clearInterval( interval );
			interval = setInterval( update, 0 );
		}

		public function update():void
		{
			iterations++;
			
			var step:Number = 1;
			var dx:Number;
			var dy:Number;
			//var dead:Vector.<Dot> = new Vector.<Dot>();
			var i:int;
			for ( i = 0; i < pts.length; i++ )
			{
				
				p = pts[ i ];
				
				displace( p );
				
					
				var c:uint = bd.getPixel32( p.x, p.y );
				
				if ( ( p.x > 0 && p.x < bd.width &&  p.y > 0 && p.y < bd.height ) && c == 0 )//( c == 0 || c == colors[ p.id % colors.length ] ) )//
				{
					
					bd.setPixel32( p.x, p.y, colors[ p.id % colors.length ] );
					tracks.push( p.cloneDot() );
					
				}
				else
				{
					if ( tracks.length > 0 ) 
					{
						var r:int = int( Math.random() * tracks.length );
						p = pts[ i ] = tracks[ r ];
						
						//p.z += ( Math.random() > .5 ) ? -Math.PI / 2:Math.PI / 2 ;
						//p.z += ( Math.random() * .5 );
						//p.z += Math.PI / 20;
						//p.z += Math.PI / 3;
						p.z += Math.cos( p.x*p.y );
						
						var angle:Number = ( Math.PI / 180 ) * 90
						if ( Math.random() > .5 ) p.z += angle;
						else p.z -= angle;
						
						bd.setPixel32( p.x, p.y, colors[ p.id % colors.length ] );
						tracks.splice( r, 1 );
					}
				}
				
			}
			/*
			if ( tracks.length > 0 )
			{
				i = dead.length;
				while( i-- )
				{
					if ( dead[ i ] != null )
					{
						
						
						//var seed:Number = Math.random();
						//if ( seed > .25 ) p.z += Math.PI / 6;
						//if ( seed > .5 ) p.z += Math.PI / 2;
						//if ( seed > .75 ) p.z -= Math.PI / 2;
						//if ( seed > .9 ) p.z *= Math.PI / 2;
						//p.z = Math.random() * Math.PI * 2 ;
						
						//tracks.splice( r, 1 );
					}
				}
			}
			*/
			//bd.colorTransform( bd.rect, new ColorTransform(1, 1, 1, .999) );
			
		}

		public function get displace():Function { return _displace; }
		
		public function set displace(value:Function):void 
		{
			_displace = value;
		}
		
	}

}